package com.java110.mall.cart.cmd.storeOrder;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.java110.core.annotation.Java110Cmd;
import com.java110.core.client.RestTemplate;
import com.java110.core.context.ICmdDataFlowContext;
import com.java110.core.event.cmd.Cmd;
import com.java110.core.event.cmd.CmdEvent;
import com.java110.core.factory.GenerateCodeFactory;
import com.java110.core.factory.WechatFactory;
import com.java110.dto.onlinePay.OnlinePayDto;
import com.java110.dto.storeOrder.StoreOrderDto;
import com.java110.dto.storeOrder.StoreOrderCartDto;
import com.java110.dto.storeOrder.StoreOrderCartEventDto;
import com.java110.dto.storeOrder.StoreOrderLogisticsDto;
import com.java110.intf.acct.IOnlinePayV1InnerServiceSMO;
import com.java110.intf.cart.*;
import com.java110.intf.goods.IShopDistributionModeInnerServiceSMO;
import com.java110.po.storeOrder.StoreOrderPo;
import com.java110.po.storeOrder.StoreOrderCartPo;
import com.java110.po.storeOrder.StoreOrderCartEventPo;
import com.java110.po.storeOrder.StoreOrderLogisticsPo;
import com.java110.utils.cache.MappingCache;
import com.java110.utils.constant.WechatConstant;
import com.java110.utils.exception.CmdException;
import com.java110.utils.util.Assert;
import com.java110.utils.util.BeanConvertUtil;
import com.java110.utils.util.ListUtil;
import com.java110.utils.util.StringUtil;
import com.java110.vo.ResultVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

@Java110Cmd(serviceCode = "storeOrder.sendStoreOrderCart")
public class SendStoreOrderCartCmd extends Cmd {
    private static Logger logger = LoggerFactory.getLogger(SendStoreOrderCartCmd.class);

    @Autowired
    private IStoreOrderCartInnerServiceSMO storeOrderCartInnerServiceSMOImpl;

    @Autowired
    private IStoreOrderInnerServiceSMO storeOrderInnerServiceSMOImpl;

    @Autowired
    private IStoreOrderCartEventInnerServiceSMO storeOrderCartEventInnerServiceSMOImpl;
    @Autowired
    private IShopDistributionModeInnerServiceSMO shopDistributionModeInnerServiceSMOImpl;
    @Autowired
    private IStoreOrderCartSendInnerServiceSMO storeOrderCartSendInnerServiceSMOImpl;

    @Autowired
    private IStoreOrderLogisticsV1InnerServiceSMO storeOrderLogisticsV1InnerServiceSMOImpl;

    @Autowired
    private IOnlinePayV1InnerServiceSMO onlinePayV1InnerServiceSMOImpl;

    @Autowired
    private RestTemplate outRestTemplate;

    @Override
    public void validate(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {
        Assert.hasKeyAndValue(reqJson, "orderId", "请求报文中未包含orderId");
        Assert.hasKeyAndValue(reqJson, "shopId", "shopId不能为空");
        Assert.hasKeyAndValue(reqJson, "sendWay", "派送方式不能为空");
        String sendWay = reqJson.getString("sendWay");

        // 自送
        if ("SEFT".equals(sendWay)) {
            return;
        }
        Assert.hasKeyAndValue(reqJson, "solCompany", "快递公司不能为空");
        Assert.hasKeyAndValue(reqJson, "solNum", "快递单号不能为空");

    }

    @Override
    public void doCmd(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {
        StoreOrderCartPo storeOrderCartPo = BeanConvertUtil.covertBean(reqJson, StoreOrderCartPo.class);

        //这里存在bug 目前商城只能支持 自送方式
        storeOrderCartPo.setState(StoreOrderCartDto.STATE_SENDING);
        saveCartEvent(reqJson, storeOrderCartPo);
        int flag = storeOrderCartInnerServiceSMOImpl.updateStoreOrderCart(storeOrderCartPo);
        if (flag < 0) {
            throw new CmdException("发货失败");
        }
        StoreOrderPo storeOrderPo = new StoreOrderPo();
        storeOrderPo.setOrderId(reqJson.getString("orderId"));
        storeOrderPo.setState(StoreOrderDto.STATE_WAIT_RECIVE);
        flag = storeOrderInnerServiceSMOImpl.updateStoreOrder(storeOrderPo);
        if (flag < 0) {
            throw new CmdException("发货失败");
        }
        //todo 调用微信小程序发货接口
        sendWechatMiniSendGoods(storeOrderCartPo.getOrderId(), 2);

        String sendWay = reqJson.getString("sendWay");
        // 自送
        if ("SEFT".equals(sendWay)) {
            return;
        }
        // 保存快递信息
        StoreOrderLogisticsPo storeOrderLogisticsPo = new StoreOrderLogisticsPo();
        storeOrderLogisticsPo.setCurPos("未知");
        storeOrderLogisticsPo.setSolId(GenerateCodeFactory.getGeneratorId("11"));
        storeOrderLogisticsPo.setOrderId(storeOrderCartPo.getOrderId());
        storeOrderLogisticsPo.setSolCompany(reqJson.getString("solCompany"));
        storeOrderLogisticsPo.setRemark(reqJson.getString("remark"));
        storeOrderLogisticsPo.setState(StoreOrderLogisticsDto.STATE_W);
        storeOrderLogisticsPo.setShopId(reqJson.getString("shopId"));
        storeOrderLogisticsPo.setSolNum(reqJson.getString("solNum"));
        storeOrderLogisticsV1InnerServiceSMOImpl.saveStoreOrderLogistics(storeOrderLogisticsPo);



        ResponseEntity responseEntity = ResultVo.createResponseEntity(ResultVo.CODE_OK, "保存成功");
        cmdDataFlowContext.setResponseEntity(responseEntity);
    }

    /**
     * 调用微信小程序发货
     *
     * @param orderId
     * @param sendWay 物流模式，发货方式枚举值：1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品，虚拟商品，例如话费充值，点卡等，无实体配送形式 4、用户自提
     */
    private void sendWechatMiniSendGoods(String orderId, int sendWay) {
        String appId = MappingCache.getValue(WechatConstant.MALL_WECHAT_DOMAIN, "wechatAppId");
        String appSecret = MappingCache.getValue(WechatConstant.MALL_WECHAT_DOMAIN, "wechatAppSecret");

        OnlinePayDto onlinePayDto = new OnlinePayDto();
        onlinePayDto.setOrderId(orderId);
        List<OnlinePayDto> onlinePayDtos = onlinePayV1InnerServiceSMOImpl.queryOnlinePays(onlinePayDto);
        if (ListUtil.isNull(onlinePayDtos)) {
            return;
        }

        StoreOrderCartDto storeOrderCartDto = new StoreOrderCartDto();
        storeOrderCartDto.setOrderId(orderId);
        List<StoreOrderCartDto> storeOrderCartDtos = storeOrderCartInnerServiceSMOImpl.queryStoreOrderCarts(storeOrderCartDto);
        String goodsName = "";
        for (StoreOrderCartDto tmpStoreOrderCartDto : storeOrderCartDtos) {
            goodsName += (tmpStoreOrderCartDto.getProdName() + "*" + tmpStoreOrderCartDto.getCartNum() + ";");
        }
        if (StringUtil.isEmpty(goodsName)) {
            goodsName = "商城商品";
        }


        String accessToken = WechatFactory.getAccessToken(appId, appSecret);
        String url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + accessToken;
        JSONObject paramIn = new JSONObject();
        JSONObject order_key = new JSONObject();
        order_key.put("order_number_type", 1);
        order_key.put("out_trade_no", orderId);
        order_key.put("mchid", onlinePayDtos.get(0).getMchId());
        paramIn.put("order_key", order_key);
        paramIn.put("logistics_type", sendWay);
        paramIn.put("delivery_mode", 1);//发货模式，发货模式枚举值：1、UNIFIED_DELIVERY（统一发货）2、SPLIT_DELIVERY（分拆发货） 示例值: UNIFIED_DELIVERY

        JSONArray shipping_list = new JSONArray();

        JSONObject shipping = new JSONObject();
        shipping.put("item_desc", goodsName);
        shipping_list.add(shipping);
        paramIn.put("shipping_list", shipping_list);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
        // 设置时区（东八区）
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        // 格式化当前时间
        String formattedDateTime = sdf.format(new Date());
        paramIn.put("upload_time", formattedDateTime);
        JSONObject payer = new JSONObject();
        payer.put("openid", onlinePayDtos.get(0).getOpenId());
        paramIn.put("payer", payer);

        ResponseEntity<String> responseEntity = outRestTemplate.postForEntity(
                url, paramIn.toJSONString(), String.class);
        logger.debug("调用微信发货接口：{},请求报文：{},返回报文：{}", url, paramIn.toJSONString(), responseEntity);

    }

    /**
     * 保存购物车
     *
     * @param reqJson
     * @param storeOrderCartPo
     */
    private void saveCartEvent(JSONObject reqJson, StoreOrderCartPo storeOrderCartPo) {
        StoreOrderCartDto storeOrderCartDto = new StoreOrderCartDto();
        storeOrderCartDto.setOrderId(reqJson.getString("orderId"));
        storeOrderCartDto.setCartId(reqJson.getString("cartId"));
        List<StoreOrderCartDto> storeOrderCartDtos = storeOrderCartInnerServiceSMOImpl.queryStoreOrderCarts(storeOrderCartDto);
        for (StoreOrderCartDto tmpStoreOrderCartDto : storeOrderCartDtos) {
            StoreOrderCartEventPo storeOrderCartEventPo = new StoreOrderCartEventPo();
            storeOrderCartEventPo.setCartId(tmpStoreOrderCartDto.getCartId());
            storeOrderCartEventPo.setOrderId(storeOrderCartPo.getOrderId());
            storeOrderCartEventPo.setEventId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_eventId));
            storeOrderCartEventPo.setEventObjType("S");
            storeOrderCartEventPo.setEventObjId(reqJson.getString("userId"));
            storeOrderCartEventPo.setEventMsg("商家配送中");
            storeOrderCartEventPo.setShopId(storeOrderCartPo.getShopId());
            storeOrderCartEventPo.setEventType(StoreOrderCartEventDto.EVENT_TYPE_EXPEDITING_SENDING);
            int flag = storeOrderCartEventInnerServiceSMOImpl.saveStoreOrderCartEvent(storeOrderCartEventPo);
            if (flag < 1) {
                throw new IllegalArgumentException("保存购物车事件失败");
            }
        }
    }
}
